package auth

import (
	model "admin/models/auth"

	"gorm.io/gorm"
)

// MenuRepoInterface 菜单仓库接口
type MenuRepoInterface interface {
	List() ([]model.Menu, error)
	Create(menu *model.Menu) error
	Update(menu *model.Menu) error
	Delete(id int64) error
	GetMenuTree() ([]model.Menu, error)
	GetMenuByID(id int64) (*model.Menu, error)
	GetMenusByParentID(parentID int64) ([]model.Menu, error)
}

// MenuRepo 基于GORM的菜单仓库实现
type MenuRepo struct {
	db *gorm.DB
}

// NewMenuRepo 创建基于GORM的菜单仓库实例
// db: GORM数据库连接
// 返回值: 菜单仓库实例指针
func NewMenuRepo(db *gorm.DB) *MenuRepo {
	return &MenuRepo{
		db: db,
	}
}

// List 获取菜单列表
// 返回值: 菜单列表和错误信息
func (r *MenuRepo) List() ([]model.Menu, error) {
	var menus []model.Menu
	// 查询所有菜单
	err := r.db.Find(&menus).Error
	return menus, err
}

// Create 创建菜单
// menu: 菜单对象
// 返回值: 错误信息
func (r *MenuRepo) Create(menu *model.Menu) error {
	// 使用GORM创建菜单
	return r.db.Create(menu).Error
}

// Update 更新菜单
// menu: 菜单对象
// 返回值: 错误信息
func (r *MenuRepo) Update(menu *model.Menu) error {
	// 使用GORM保存菜单
	return r.db.Save(menu).Error
}

// Delete 删除菜单
// id: 菜单ID
// 返回值: 错误信息
func (r *MenuRepo) Delete(id int64) error {
	// 使用GORM删除指定ID的菜单
	return r.db.Delete(&model.Menu{}, id).Error
}

// GetMenuByID 根据ID获取菜单
// id: 菜单ID
// 返回值: 菜单对象和错误信息
func (r *MenuRepo) GetMenuByID(id int64) (*model.Menu, error) {
	var m model.Menu
	// 根据ID查询菜单
	if err := r.db.First(&m, id).Error; err != nil {
		return nil, err
	}
	return &m, nil
}

// GetMenuTree 获取菜单树
// 返回值: 菜单树和错误信息
func (r *MenuRepo) GetMenuTree() ([]model.Menu, error) {
	// 获取所有菜单
	menus, err := r.List()
	if err != nil {
		return nil, err
	}

	// 构建菜单树
	return buildMenuTree(menus, 0), nil
}

// GetMenusByParentID 根据父级ID获取菜单列表
// parentID: 父级菜单ID
// 返回值: 菜单列表和错误信息
func (r *MenuRepo) GetMenusByParentID(parentID int64) ([]model.Menu, error) {
	var menus []model.Menu
	err := r.db.Where("parent_id = ?", parentID).Find(&menus).Error
	return menus, err
}

// buildMenuTree 构建菜单树
// menus: 菜单列表
// parentID: 父级ID
// 返回值: 菜单树
func buildMenuTree(menus []model.Menu, parentID int64) []model.Menu {
	var tree []model.Menu

	for _, menu := range menus {
		if menu.ParentID == parentID {
			// 递归获取子菜单
			children := buildMenuTree(menus, menu.ID)
			menu.Children = children
			tree = append(tree, menu)
		}
	}

	return tree
}
